package com.lhg.common.aspect;

import com.lhg.common.page.ResultInfo;
import com.lhg.common.util.CommonUtils;
import com.lhg.common.util.JsonUtil;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 用于记录后台访问
 * 记录的请求信息：
 * <p>
 * 请求ip
 * 请求url
 * 请求参数
 * 调用的controller及方法
 * </p>
 * 记录的响应信息
 * <p>
 * 返回的数据
 * </p>
 * <p>
 * controller层方法被调用前后才会执行这个切面，如果被拦截器拦截，此切面调用不到
 */
@Aspect
@Component
public class VisitLogAspect {
    private static Logger logger = Logger.getLogger(VisitLogAspect.class);

    @Resource
    private HttpServletRequest request;

    @Pointcut("execution(* com.lhg.*.controller..*(..))")
    public void log() {
        logger.info(JsonUtil.toJson(request.getParameterMap()));
    }

    @Before("log()")
    public void before(JoinPoint joinPoint) {
        StringBuilder sb = new StringBuilder("\n----------------------SpringMVC request report start ")
                .append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))
                .append(" ------------------------------\n");
        sb.append("ip          : " + CommonUtils.getIpAddr(request)).append("\n");
        String uri = request.getRequestURI();
        if (uri != null) {
            sb.append("url         : ").append(uri).append("\n");
        }
        sb.append("parameter   : " + JsonUtil.toJson(request.getParameterMap()));
        sb.append("\n");
        sb.append("controller  : ").append(joinPoint.getTarget().getClass().getName()).append(".(")
                .append(joinPoint.getTarget().getClass().getSimpleName()).append(".java:1)");
        sb.append("\nmethod      : ").append(joinPoint.getSignature().getName()).append("\n");
        sb.append("----------------------SpringMVC request report end ----------------------------------------------------\n");
        String requestInfo = sb.toString();
        System.out.print(requestInfo);
        logger.debug(requestInfo);
    }

    @AfterReturning(pointcut = "log()", returning = "returnValue")
    public void afterReturning(JoinPoint joinPoint, Object returnValue) {
        if (returnValue != null) {
            StringBuilder sb = new StringBuilder("\n----------------------SpringMVC response report start ").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())).append(" ------------------------------\n");
            if (returnValue instanceof ResultInfo) {
                sb.append("returnValue : " + JsonUtil.toJson(returnValue)).append("\n");
            } else {
                sb.append("returnValue : " + JsonUtil.toJson(returnValue)).append("\n");
            }
            sb.append("returnType  : " + returnValue.getClass().getTypeName()).append("\n");
            sb.append("----------------------SpringMVC response report end ----------------------------------------------------\n");
            String responseInfo = sb.toString();
            System.out.print(responseInfo);
            logger.debug(responseInfo);
        }
    }

}